package com.cong.security.app.authentication;

import com.cong.security.core.code.SmsCodeFilter;
import com.cong.security.core.code.sms.SmsCodeAuthenticationSecurityConfig;
import com.cong.security.core.code.sms.SmsCodeSender;
import com.cong.security.core.constant.UrlConstants;
import com.cong.security.core.properties.SecurityProperties;
import com.cong.security.core.social.app.OpenIdAuthenticationSecurityConfig;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpMethod;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableResourceServer;
import org.springframework.security.oauth2.config.annotation.web.configuration.ResourceServerConfigurerAdapter;
import org.springframework.security.web.authentication.AuthenticationFailureHandler;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
import org.springframework.social.connect.UsersConnectionRepository;
import org.springframework.social.security.SpringSocialConfigurer;
import org.springframework.web.cors.CorsUtils;

@Configuration
@EnableResourceServer
public class MyResourceServerConfig<AuthorizeConfigManager> extends ResourceServerConfigurerAdapter {
    // 安全配置
    @Autowired
    private SecurityProperties securityProperties;
    // 成功处理器
    @Autowired
    private AuthenticationSuccessHandler myAuthenticationSuccessHandler;
    // 失败处理器
    @Autowired
    private AuthenticationFailureHandler myAuthenticationFailureHandler;
    // 短信登录
    @Autowired
    private SmsCodeAuthenticationSecurityConfig smsCodeAuthenticationSecurityConfig;
    // 三方登录
    @Autowired
    private SpringSocialConfigurer mySocialSecurityConfig;
    // 短信发送接口
    @Autowired
    private SmsCodeSender smsCodeSender;
    // 三方账户绑定
    @Autowired
    private UsersConnectionRepository usersConnectionRepository;
    // 三方登录
    @Autowired
    private OpenIdAuthenticationSecurityConfig openIdAuthenticationSecurityConfig;

    @Override
    public void configure(HttpSecurity http) throws Exception {
        SmsCodeFilter smsCodeFilter = new SmsCodeFilter();
        smsCodeFilter.setMyAuthenticationFailureHandler(myAuthenticationFailureHandler);
        smsCodeFilter.setSecurityProperties(securityProperties);
        smsCodeFilter.setSmsCodeSender(smsCodeSender);
        smsCodeFilter.setUsersConnectionRepository(usersConnectionRepository);
        // 初始化方法
        smsCodeFilter.afterPropertiesSet();

        http.authorizeRequests().antMatchers(HttpMethod.OPTIONS).permitAll();// 放行预请求

        http.formLogin()
                .loginProcessingUrl("/app/login")// 系统登陆请求路径为/app/login，此处设置目的是使用UsernamePasswordAuthenticationFilter处理此处登录请求
                .successHandler(myAuthenticationSuccessHandler)// 自定义成功处理器
                .failureHandler(myAuthenticationFailureHandler);// 自定义失败处理器
        http.addFilterBefore(smsCodeFilter, UsernamePasswordAuthenticationFilter.class)// 在用户名密码校验之前添加验证码校验
                .apply(mySocialSecurityConfig)// 三方登录
                .and().apply(smsCodeAuthenticationSecurityConfig)// 短信验证码
                .and().apply(openIdAuthenticationSecurityConfig)// openId登录
                .and().authorizeRequests()
                .antMatchers(UrlConstants.DEFAULT_APP_SOCIAL_SIGN_UP_URL).permitAll()// 注册页授权
                .requestMatchers(CorsUtils::isPreFlightRequest).permitAll()// 解决浏览器端预请求直接放过,不作处理
                .and().csrf().disable();// 跨站请求访问
    }
}
